import { Component } from 'react';
import { ButtonGroup,Button,AnchorButton } from '@blueprintjs/core';
import {contain, isEmptyObject} from '../../../utils/util';
import {CreateMapInstance, createFullscreenControl} from '../../../map/map';
import styles from './Center.less';
import { connect } from 'dva';
import { updateState } from '../../../models/global';
import {ToasterWarning} from '../../../components/Toaster';
import { HighlightStyle } from '../../../map/style';
import {flashLayer} from '../../../utils/animate';

class Center extends Component {
    constructor(props) {
        super(props);
		this.state = {

		}
		this.mapPane = React.createRef();
		this.map = null;
	}

	initMap() {
		const container = this.mapPane.current;
		const map = this.map = window.map = CreateMapInstance({
			container,
			style: window.ATCONFIG.mapId || "atlasdata://maps/x/K4gAfxnZR/",
		});
		updateState({map});
		const {sync}  = this.props;
		map.on("load", () => {
		// setTimeout(() => {
			this.initControl();

			// 测量工具
			const measureTool = map.measureTool = new atlas.MeasureTool(map, {
			    cursor: "url(./images/cur/ruler.cur), auto"
			});

			this.inspectorPopup =  new atlas.Popup({className:'atlas-popup-a'});

			this.mousePopup = new atlas.Popup({offset: [0, 0], closeOnClick: false});

			const bbox = {width: 10, height: 10};
			map.on("mousemove", (e) => {
				updateState({mouseInMap: "map"});
				if(measureTool.isActivate()) return;
				try {
					const feature = map.queryRenderedFeatures([
						[e.point.x - bbox.width / 2, e.point.y - bbox.height / 2],
						[e.point.x + bbox.width / 2, e.point.y + bbox.height / 2]
					])[0];
					map.setCursor(feature && this.isDmdzLayer(feature.layer) ? "pointer" : "");
				} catch {

				}
			});

			map.on("move", () => {
				sync("map");
			});
			map.on("moveend", () => {
				sync("map");
			});

			map.on("click", (e) => {
			    if(measureTool.isActivate()) return;
			    this._mapFeatureClick(e);
			});
		// },1000)
		});
    }

    isDmdzLayer = (layer) => {
        return layer && layer.metadata && contain(['roads', 'houses', 'buildings'], layer.metadata.name) >= 0
	}

	initControl = () => {
        const map = this.map;
        if(!map) return;
        map.addControl(new atlas.NavigationControl(),"bottom-left");

        const FullscreenControl = createFullscreenControl();
        if(FullscreenControl) {
            const fullControl = new FullscreenControl();
            fullControl.setEvent({
                request: () => {
                    // console.log("fullscreen")
                },
                exit: () => {
                    // console.log("exitscreen")
                }
            })
            map.addControl(fullControl,"bottom-left");
        }

    }

	componentDidMount() {
		this.initMap();
    }

	/**
	 * 从地图中移除定位结果
	 */
	removeLocate = () => {
		const {map,sign} = this.props;
		if(map) {
			clearInterval(sign);
			cancelAnimationFrame(sign);
			const {marker} = this.state;
			if(marker) marker.remove();
			const layerId = 'dmdz-locate-layer';
			const layer = map.getLayer(layerId);
			if(layer) {
				map.removeLayer(layerId);
			}
			const layer1 = map.getLayer('searchLayer1');
			if(layer1) {
			    map.removeLayer('searchLayer1');
			}
			const layer2 = map.getLayer('searchLayer2');
			if(layer2) {
			    map.removeLayer('searchLayer2');
			}
			const layer4 = map.getLayer('atlasdata-ext-dmdz-roads-source-layer');
			if(layer4) {
				map.removeLayer('atlasdata-ext-dmdz-roads-source-layer')
			}
			const layer5 = map.getLayer('atlasdata-ext-dmdz-focus-poi-source');
			if(layer5) {
				map.removeLayer('atlasdata-ext-dmdz-focus-poi-source')
			}
			const layer6 = map.getLayer('dmdz-locate-layer-circle');
			if(layer6) {
				map.removeLayer('dmdz-locate-layer-circle')
			}
		}
	}

	// 移除点击结果
	removeMapClickResult = () => {
		const {map} = this;
		if(!map) return;
		const sources = [
			"atlasdata-ext-dmdz-roads-source",
			"atlasdata-ext-dmdz-focus-poi-source",
			"atlasdata-ext-searchSource",
			"atlasdata-ext-locateSource", // 街道定位
			"atlasdata-ext-locateSource-point", // POI定位
		];
		sources.map((sourceId) => {
			const source = map.getSource(sourceId);
			if(source) {
				source.setData({
					type: "FeatureCollection",
					features: []
				});
			}
		});
	}

	/** 道路信息 */
	focusOnRoads = (feature, e) => {
		if(!feature) return;
		const props = feature.properties;
		const geom = feature.geometry;
		const map = this.map;
		if(!props || !props.gid || !map) return;
		const {roadDataset, street, setSelectedFeature} = this.props;
		ajax_get({
			url: `/dm/list/${props.gid}/`,
			data: {type: 'roads'}
		}).then((res) => {
			if(!res) return;
			const result = res.data && res.data.length && res.data[0]
			if(!result) {
				ToasterWarning({message: `未获取到${props.name}的信息`});
				return;
			}
			result.point = e.point;
			// 加载属性面板
			setSelectedFeature && setSelectedFeature(result);
			// 空间信息定位
			if(!result.geom) {
				ToasterWarning({message: `未获取到${props.name}的定位信息，无法定位`});
				return;
			}
			const sourceId = 'atlasdata-ext-dmdz-roads-source';
			const source = map.getSource(sourceId);
			if(!source) {
				map.addSource(sourceId, {
					type: 'geojson',
					data: {
						type: "FeatureCollection",
						features: [{
							type: 'Feature',
							geometry: geom,
							properties: result
						}]
					}
				});
			} else {
				source.setData({
					type: "FeatureCollection",
					features: [{
						type: 'Feature',
						geometry: geom,
						properties: result
					}]
				});
			}
			const layerId = sourceId + '-layer';
			if(!map.getLayer(layerId)) {
				map.addLayer({
					id: layerId,
					source: sourceId,
					'type': 'line',
					paint: {
						'line-color': '#08F',
						'line-opacity': 0.7,
						'line-width': 10,
					}
				});
				let sign = flashLayer({
				    map: map,
				    layer: layerId,
				    type: 'paint',
				    property: 'line-color',
					on: '#08F',
					off: '#000',
				    interval: 200,
				    // timer: 3000,
				    end: () => {
				        map.setLayoutProperty(layerId, 'visibility', 'none');
				    }
				});
				updateState({sign})
			}
		})
	}

	/** 道路信息 */
	focusOnPOI = (feature, type, e) => {
		if(!feature || !type) return;
		const props = feature.properties;
		const geom = feature.geometry;
		const map = this.map;
		if(!props || !props.gid || !map) return;
		const {roadDataset, street, setSelectedFeature} = this.props;
		ajax_get({
			url: `/dm/list/${props.gid}/`,
			data: {type}
		}).then((res) => {
			if(!res) return;
			const result = res.data[0]
			if(!result) {
				ToasterWarning({message: `未获取到${props.name}的信息`});
				return;
			}
			result.point = e.point;
			// 加载属性面板
			setSelectedFeature && setSelectedFeature(result);
			// 空间信息定位
			if(!result.geom) {
				ToasterWarning({message: `未获取到${props.name}的定位信息，无法定位`});
				return;
			}
			try {
				let type = geom.type;
				const sourceId = 'atlasdata-ext-dmdz-focus-poi-source';
				const source = map.getSource(sourceId);
				if(!source) {
					map.addSource(sourceId, {
						type: 'geojson',
						data: {
							type: "FeatureCollection",
							features: [{
								type: 'Feature',
								geometry: geom,
								properties: result
							}]
						}
					});
				} else {
					source.setData({
						type: "FeatureCollection",
						features: [{
							type: 'Feature',
							geometry: geom,
							properties: result
						}]
					});
				}
				const layerId = sourceId + '-layer';
				if(!map.getLayer(layerId)) {
					map.addLayer({
						id: sourceId + '-layer',
						source: sourceId,
						'type': 'circle',
						paint: {
							'circle-color': '#08F',
							'circle-opacity': 0.7,
							'circle-radius': 10,
						},
						metadata: {
							name: "定位图层"
						}
					});
				}
				let sign = flashLayer({
				    map: map,
				    layer: layerId,
				    type: 'paint',
				    property: 'circle-color',
					on: '#08F',
					off: '#000',
				    interval: 200,
				    // timer: 3000,
				    end: () => {
				        map.setLayoutProperty(layerId, 'visibility', 'none');
				    }
				});
				updateState({sign})
			} catch {
			}
		})
	}

    _mapFeatureClick = (e) => {
        const map = this.map;
        if(!map) return;
		this.removeLocate();
		this.removeMapClickResult();
        const bbox = {width: 10, height: 10};
        const feature = map.queryRenderedFeatures([
            [e.point.x - bbox.width / 2, e.point.y - bbox.height / 2],
            [e.point.x + bbox.width / 2, e.point.y + bbox.height / 2]
		])[0];
        if(feature && feature.properties) {
			// this.mousePopup.remove();
			const layer = feature.layer;
			const type = layer && layer.metadata && layer.metadata.name;
			switch(type) {
				case "roads":
					this.focusOnRoads(feature, e);
					break;
				case "buildings":
				case "houses":
					this.focusOnPOI(feature, type, e);
					break;
				default:
					break;
			}
        }
    }

    render() {

        return (
			<div id="map" ref={this.mapPane} className={styles.main}>

			</div>
        )
    }
}

function mapStateToProps(state) {
    return {
        roadDataset: state.map.roadDataset,
		sign: state.map.sign
    };
}

export default connect(mapStateToProps)(Center);
